#include "MainDialog.h"
#include "ui_MainDialog.h"
#include "SettingsManagerSingleton.h"
#include "CameraSettingsManagerSingleton.h"
#include "EmailManagerSingleton.h"
#include <QMessageBox>
#include <QCameraImageCapture>
#include <QCameraImageProcessing>
#include <QVideoEncoderSettings>
#include <QAudioEncoderSettings>
#include <QMediaRecorder>
#include <QDir>
#include <QUrl>
#include <QDesktopServices>
#include <QFileDialog>

//================================================
//================================================
MainDialog::MainDialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::MainDialog){
    ui->setupUi(this);
    this->timerAutoSnapping = new QTimer(this);
    this->timerMotion = new QTimer(this);
    this->lastTabIndex = this->ui->tabWidget->currentIndex();
    this->currentMode = MainDialog::CameraOff;
    this->ui->tableWidgetMode
                    ->setEditTriggers(QAbstractItemView::NoEditTriggers);
    this->_loadAvailableWebcams();
    this->_initCameraFromPreviousSession();
    this->_loadSettings();
    this->_connectSlots();
    this->changeModeAndSetCameraOffMode();
}
//================================================
void MainDialog::changeModeAndSetCameraOffMode(){
    this->ui->tableWidgetMode->setCurrentCell(1, 0);
    this->onSelectionTableCellChanged(1, 0);
}
//================================================
MainDialog::~MainDialog(){
    delete ui;
}
//================================================
void MainDialog::_loadSettings(){
    SettingsManagerSingleton *settingsManager
                    = SettingsManagerSingleton::getInstance();
    //Paths
    QString imagesDirPath = settingsManager->getImagesDirPath();
    this->ui->lineEditImagesDirectory->setText(imagesDirPath);
    QString videosDirPath = settingsManager->getVideosDirPath();
    this->ui->lineEditVideosDirectory->setText(videosDirPath);
    QString autoSnappingDirPath
                    = settingsManager->getAutoSnappingDirPath();
    this->ui->lineEditAutoSnappingDirectory
                    ->setText(autoSnappingDirPath);
    QString motionDirPath = settingsManager->getMotionDirPath();
    this->ui->lineEditMotioDirectory->setText(motionDirPath);
    //Email
    int serverPort = settingsManager->getServerPort();
    this->ui->spinBoxServorPort->setValue(serverPort);
    QString serverAddress = settingsManager->getServerAddress();
    this->ui->lineEditServorAddress->setText(serverAddress);
    QString emailSender = settingsManager->getEmailSender();
    this->ui->lineEditEmailSender->setText(emailSender);
    QString passwordSender = settingsManager->getPasswordSender();
    this->ui->lineEditPasswordSender->setText(passwordSender);
    bool hidePassword = settingsManager->getHidePasswordSender();
    if(hidePassword){
        this->ui->lineEditPasswordSender
                        ->setEchoMode(QLineEdit::Password);
    }
    this->ui->checkBoxHidePasswordSender->setChecked(hidePassword);
    bool dontRememberPasswordSender
                    = settingsManager->getDontRememberPasswordSender();
    this->ui->checkBoxDontRememberPasswordSender
                    ->setChecked(dontRememberPasswordSender);
    QString emailReceivers = settingsManager->getEmailReceivers();
    this->ui->lineEditReceiverAddresses->setText(emailReceivers);
    //Auto snapping
    QTime intervalTimeAutoSnapping
                    = settingsManager->getAutoSnappingTimeInterval();
    this->ui->timeEditAutoSnappingTimeInterval
                    ->setTime(intervalTimeAutoSnapping);
    bool sendEmailAutoSnapping
                    = settingsManager->getAutoSnappingSendEmail();
    this->ui->checkBoxAutoSnappingSendEmail
                    ->setChecked(sendEmailAutoSnapping);
    //Motion
    int intervalTimeMotionInMs
                    = settingsManager->getMotionTimeInterval();
    this->ui->spinBoxMotionTimeInterval
                    ->setValue(intervalTimeMotionInMs);
    int sensibility = settingsManager->getMotionSensibility();
    this->ui->sliderMotionSensibility->setValue(sensibility);
    bool sendEmail = settingsManager->getMotionSendEmail();
    this->ui->checkBoxMotionSendEmail->setChecked(sendEmail);
    bool sendImage = settingsManager->getMotionSendEmailWithImage();
    this->ui->checkBoxMotionEmailWithImage->setChecked(sendImage);
    bool saveImage = settingsManager->getMotionSaveImage();
    this->ui->radioButtonMotionSaveImages->setChecked(saveImage);
    bool saveVideo = settingsManager->getMotionSaveVideo();
    this->ui->radioButtonMotionSaveVideos->setChecked(saveVideo);
    bool save = settingsManager->getMotionSave();
    this->ui->groupBoxMotionSave->setChecked(save);
    this->ui->radioButtonMotionSaveImages->setEnabled(save);
    this->ui->radioButtonMotionSaveVideos->setEnabled(save);
}
//================================================
void MainDialog::_connectSlots(){
    qDebug() << "Connecting slots...";
    this->_connectMainTabSlots();
    this->_connectCameraSettingsSlots();
    this->_connectSettingsSlots();
    qDebug() << "Slots connected";
}
//================================================
void MainDialog::_connectMainTabSlots(){
    qDebug() << "Connecting main tab slots...";
    this->connect(this->ui->comboBoxCamera,
                  SIGNAL(currentIndexChanged(int)),
                  SLOT(setCamera(int)));
    this->connect(this->ui->tabWidget,
                  SIGNAL(currentChanged(int)),
                  SLOT(onTabIndexChanged(int)));
    this->connect(this->ui->pushButtonRecord,
                  SIGNAL(clicked()),
                  SLOT(record()));
    this->connect(this->ui->pushButtonShowDirectory,
                  SIGNAL(clicked()),
                  SLOT(showDirectory()));
    this->connect(this->timerAutoSnapping,
                  SIGNAL(timeout()),
                  SLOT(_recordAndSendImage()));
    this->connect(this->timerMotion,
                  SIGNAL(timeout()),
                  SLOT(_recordAndSendImageMotionEventually()));
    EmailManagerSingleton *emailManager
                    = EmailManagerSingleton::getInstance();
    this->connect(emailManager,
                  SIGNAL(authenticationFailed(QByteArray)),
                  SLOT(authenticationFailed(QByteArray)));
    this->connect(emailManager,
                  SIGNAL(connectionFailed(QByteArray)),
                  SLOT(connectionFailed(QByteArray)));
    this->connect(emailManager,
                  SIGNAL(mailFailed(int, int, QByteArray)),
                  SLOT(mailFailed(int, int, QByteArray)));
    qDebug() << "Main tab slots connected";
}
//================================================
void MainDialog::_connectCameraSettingsSlots(){
    qDebug() << "Connecting camera settings slots...";
    this->connect(this->ui->sliderBrightness,
                  SIGNAL(sliderMoved(int)),
                  SLOT(setBrightness(int)));
    this->connect(this->ui->sliderContrast,
                  SIGNAL(sliderMoved(int)),
                  SLOT(setContrast(int)));
    this->connect(this->ui->sliderSaturation,
                  SIGNAL(sliderMoved(int)),
                  SLOT(setSaturation(int)));
    this->connect(this->ui->sliderHue,
                  SIGNAL(sliderMoved(int)),
                  SLOT(setHue(int)));
    this->connect(this->ui->tableWidgetMode,
                  SIGNAL(cellClicked(int,int)),
                  SLOT(onSelectionTableCellChanged(int,int)));
    qDebug() << "Camera settings slots connected";
}
//================================================
void MainDialog::_connectSettingsSlots(){
    qDebug() << "Connecting settings slots...";
    SettingsManagerSingleton *settingsManager
                    = SettingsManagerSingleton::getInstance();
    EmailManagerSingleton *emailManager
                    = EmailManagerSingleton::getInstance();
    //Directories
    this->connect(settingsManager,
                             SIGNAL(imagesDirPathChanged(QString)),
                             SLOT(setImagesDirPath(QString)));
    this->connect(settingsManager,
                             SIGNAL(videosDirPathChanged(QString)),
                             SLOT(setVideosDirPath(QString)));
    this->connect(settingsManager,
                             SIGNAL(autoSnappingDirPathChanged(QString)),
                             SLOT(setAutoSnappingDirPath(QString)));
    this->connect(settingsManager,
                             SIGNAL(motionDirPathChanged(QString)),
                             SLOT(setMotionDirPath(QString)));
    this->connect(this->ui->pushButtonBrowseImagesDirectory,
                             SIGNAL(clicked()),
                             SLOT(chooseImagesDirectory()));
    this->connect(this->ui->pushButtonBrowseVideosDirectory,
                             SIGNAL(clicked()),
                             SLOT(chooseVideosDirectory()));
    this->connect(this->ui->pushButtonBrowseAutoSnapping,
                             SIGNAL(clicked()),
                             SLOT(chooseAutoSnappingDirectory()));
    this->connect(this->ui->pushButtonBrowseMotion,
                             SIGNAL(clicked()),
                             SLOT(chooseMotionDirectory()));
    //Recording
    //Email
    emailManager->connect(this->ui->pushButtonEmailTest,
                          SIGNAL(clicked()),
                          SLOT(sendTestEmail()));
    emailManager->connect(settingsManager, //TODO tester
                          SIGNAL(emailInformationChanged()),
                          SLOT(disconnectOfSmtp()));
    settingsManager->connect(this->ui->lineEditEmailSender,
                             SIGNAL(textEdited(QString)),
                             SLOT(setEmailSender(QString)));
    settingsManager->connect(this->ui->lineEditPasswordSender,
                             SIGNAL(textEdited(QString)),
                             SLOT(setPasswordSender(QString)));
    settingsManager->connect(this->ui->lineEditReceiverAddresses,
                             SIGNAL(textEdited(QString)),
                             SLOT(setEmailReceivers(QString)));
    settingsManager->connect(this->ui->lineEditImagesDirectory,
                             SIGNAL(textEdited(QString)),
                             SLOT(setImagesDirPath(QString)));
    settingsManager->connect(this->ui->lineEditVideosDirectory,
                             SIGNAL(textEdited(QString)),
                             SLOT(setVideosDirPath(QString)));
    settingsManager->connect(this->ui->lineEditAutoSnappingDirectory,
                             SIGNAL(textEdited(QString)),
                             SLOT(setAutoSnappingDirPath(QString)));
    settingsManager->connect(this->ui->lineEditMotioDirectory,
                             SIGNAL(textEdited(QString)),
                             SLOT(setMotionDirPath(QString)));
    settingsManager->connect(this->ui->checkBoxHidePasswordSender,
                             SIGNAL(toggled(bool)),
                             SLOT(setHidePasswordSender(bool)));
    this->connect(settingsManager,
                             SIGNAL(hidePasswordSenderChanged(bool)),
                             SLOT(setHidePasswordSender(bool)));
    settingsManager->connect(this->ui->timeEditAutoSnappingTimeInterval,
                             SIGNAL(timeChanged(QTime)),
                             SLOT(setAutoSnappingTimeInterval(QTime)));
    //Motion
    settingsManager->connect(this->ui->spinBoxMotionTimeInterval,
                             SIGNAL(valueChanged(int)),
                             SLOT(setMotionTimeInterval(int)));
    settingsManager->connect(this->ui->sliderMotionSensibility,
                             SIGNAL(sliderMoved(int)),
                             SLOT(setMotionSensibility(int)));
    settingsManager->connect(this->ui->checkBoxMotionSendEmail,
                             SIGNAL(toggled(bool)),
                             SLOT(setMotionSendEmail(bool)));
    settingsManager->connect(this->ui->checkBoxMotionEmailWithImage,
                             SIGNAL(toggled(bool)),
                             SLOT(setMotionSendEmailWithImage(bool)));
    settingsManager->connect(this->ui->radioButtonMotionSaveImages,
                             SIGNAL(toggled(bool)),
                             SLOT(setMotionSaveImage(bool)));
    settingsManager->connect(this->ui->radioButtonMotionSaveVideos,
                             SIGNAL(toggled(bool)),
                             SLOT(setMotionSaveVideo(bool)));
    this->connect(this->ui->groupBoxMotionSave,
                             SIGNAL(toggled(bool)),
                             SLOT(setMotionSave(bool)));

    //Auto capture


    qDebug() << "Settings slots connected";
}
//================================================
void MainDialog::_loadAvailableWebcams(){
    qDebug() << "void MainDialog::_loadAvailableWebcams() called";
    QList<QByteArray> devices = QCamera::availableDevices();
    QByteArray byteArray;
    foreach(byteArray, devices){
        QString description = QCamera::deviceDescription(byteArray);
        this->ui->comboBoxCamera->addItem(description);
    }
    qDebug() << "void MainDialog::_loadAvailableWebcams() end";
}
//================================================
void MainDialog::_initCameraFromPreviousSession(){
    qDebug() << "void MainDialog::_initCameraFromPreviousSession() called";
    QByteArray lastCameraDevice
                    = CameraSettingsManagerSingleton::getInstance()->getLastCameraDevice();
    this->setCamera(lastCameraDevice);
    qDebug() << "void MainDialog::_initCameraFromPreviousSession() end";
}
//================================================
//================================================
void MainDialog::setCamera(int currentCameraIndex){
    qDebug() << "void MainDialog::setCamera(int currentCameraIndex &cameraDevice) called";
    QList<QByteArray> devices = QCamera::availableDevices();
    if(currentCameraIndex > 0){
        QByteArray cameraDevice = devices[currentCameraIndex-1];
        this->setCamera(cameraDevice);
        if(this->currentMode == MainDialog::CameraOff){
            this->ui->tableWidgetMode->setCurrentCell(0, 0);
            this->onSelectionTableCellChanged(0, 0);
        }
    }else{
        this->changeModeAndSetCameraOffMode();
    }
    qDebug() << "void MainDialog::setCamera(int currentCameraIndex &cameraDevice) end";
}
//================================================
void MainDialog::setCamera(const QByteArray &cameraDevice){
    qDebug() << "void MainDialog::setCamera(const QByteArray &cameraDevice) called";
    QString noCamera = "No camera";
    if(!cameraDevice.isEmpty()){
        qDebug() << "setting camera :" << cameraDevice << "...";
        if(cameraDevice != noCamera){
            this->eventuallyStopCamera(cameraDevice);
            QSharedPointer<QCamera> cameraLocal(new QCamera(cameraDevice));
            this->camera = cameraLocal;
            this->_updateAfterCameraChanged(cameraDevice);
            CameraSettingsManagerSingleton::getInstance()
                        ->setLastCameraDevice(cameraDevice);
        }else{
            this->stopCamera();
        }
        this->currentCameraDevice = cameraDevice;
    }
}
//================================================
void MainDialog::eventuallyStopCamera(const QByteArray &nextCameraDevice){
    if(!this->currentCameraDevice.isEmpty()
                    && this->currentCameraDevice != nextCameraDevice){
        this->stopCamera();
    }
}
//================================================
void MainDialog::stopCamera(){
    qDebug() << "Stoping camera...";
    if(this->camera != NULL){
        this->camera->stop();
    }
    qDebug() << "Camera stopped";
}
//================================================
void MainDialog::_updateAfterCameraChanged(const QByteArray &nextCameraDevice){
    this->setRightViewFinder();
    this->camera->start();
    //load settings
    this->ui->sliderBrightness->setValue(0);
    this->setBrightness(0);
    this->ui->sliderContrast->setValue(0);
    this->setContrast(0);
    this->ui->sliderHue->setValue(0);
    this->setHue(0);
    this->ui->sliderSaturation->setValue(0);
    this->setSaturation(0);
}
//================================================
void MainDialog::setRightViewFinder(){
    qDebug() << "void MainDialog::setRightViewFinder() called";
    if(!this->camera.isNull()){
        bool inCameraTab = this->inCameraTab();
        if(inCameraTab){
            this->camera->setViewfinder(this->ui->mainCamViewWidget);
        }else{
            this->camera->setViewfinder(this->ui->settingsCamViewWidget);
        }
    }
    qDebug() << "void MainDialog::setRightViewFinder() end";
}
//================================================
bool MainDialog::inCameraTab(){
     int currentTabIndex = this->ui->tabWidget->currentIndex();
     bool inCameraTab = currentTabIndex == MainDialog::mainCameraIndex;
     return inCameraTab;
}
//================================================
bool MainDialog::inCameraSettingsTab(){
     int currentTabIndex = this->ui->tabWidget->currentIndex();
     bool inCameraSettingsTab
                     = currentTabIndex == MainDialog::cameraSettingsIndex;
     return inCameraSettingsTab;
}
//================================================
void MainDialog::onTabIndexChanged(int tabIndex){
    if(tabIndex != this->lastTabIndex){
        if(tabIndex == MainDialog::cameraSettingsIndex
        && this->lastTabIndex == MainDialog::mainCameraIndex){
            this->_updateFromMainTabToSettingsCamera();
        }else if(tabIndex == MainDialog::mainCameraIndex
        && this->lastTabIndex == MainDialog::cameraSettingsIndex){
            this->_updateFromSettingsCameraToMainTab();
        }
    }
}
//================================================
void MainDialog::_updateFromMainTabToSettingsCamera(){
    qDebug() << "void MainDialog::_updateFromMainTabToSettingsCamera() called";
    if(!this->camera.isNull()){
        this->setRightViewFinder();
    }
    this->lastTabIndex = MainDialog::cameraSettingsIndex;
    qDebug() << "void MainDialog::_updateFromMainTabToSettingsCamera() end";
}
//================================================
void MainDialog::_updateFromSettingsCameraToMainTab(){
    qDebug() << "void MainDialog::_updateFromSettingsCameraToMainTab() called";
    if(!this->camera.isNull()){
        this->setRightViewFinder();
    }
    this->lastTabIndex = MainDialog::mainCameraIndex;
    qDebug() << "void MainDialog::_updateFromSettingsCameraToMainTab() end";
}
//================================================
void MainDialog::setBrightness(int brightness){
    this->ui->mainCamViewWidget->setBrightness(brightness);
    this->ui->settingsCamViewWidget->setBrightness(brightness);
}
//================================================
void MainDialog::setContrast(int contrast){
    this->ui->mainCamViewWidget->setContrast(contrast);
    this->ui->settingsCamViewWidget->setContrast(contrast);
    //QCameraImageProcessing *imageProcessing = this->camera->imageProcessing(); //TODO don't work
    //imageProcessing->setContrast(contrast);
}
//================================================
void MainDialog::setHue(int hue){
    this->ui->mainCamViewWidget->setHue(hue);
    this->ui->settingsCamViewWidget->setHue(hue);
}
//================================================
void MainDialog::setSaturation(int saturation){
    this->ui->mainCamViewWidget->setSaturation(saturation);
    this->ui->settingsCamViewWidget->setSaturation(saturation);
}
//================================================
void MainDialog::onSelectionTableCellChanged(int x, int y){
    if(x == 0){
        if(y == 0){
            this->setCameraOnMode();
        }else if(y == 1){
            this->setCameraImageMode();
        }else if(y == 2){
            this->setCameraVideoMode();
        }
    }else if(x == 1){
        if(y == 0){
            this->setCameraOffMode();
        }else if(y == 1){
            this->setCameraMotionMode();
        }else if(y == 2){
            this->setCameraAutoSnappingMode();
        }
    }
}
//================================================
void MainDialog::setCameraOffMode(){
    qDebug() << "void MainDialog::setCameraOffMode() called";
    this->stopCamera();
    this->ui->mainCamViewWidget->update();
    this->ui->settingsCamViewWidget->update();
    this->_setMode(MainDialog::CameraOff);
    this->ui->pushButtonRecord->setEnabled(false);
    this->ui->pushButtonRecord->setCheckable(false);
    this->ui->pushButtonShowDirectory->setEnabled(false);
    this->timerAutoSnapping->stop();
    this->timerMotion->stop();
    qDebug() << "void MainDialog::setCameraOffMode() end";
}
//================================================
void MainDialog::_setMode(RunningType mode){
    this->currentMode = mode;
    if(this->currentMode == MainDialog::CameraOff){
        this->ui->tableWidgetMode->setCurrentCell(1, 0);
    }else if(this->currentMode == MainDialog::CameraOn){
        this->ui->tableWidgetMode->setCurrentCell(0, 0);
    }else if(this->currentMode == MainDialog::Image){
        this->ui->tableWidgetMode->setCurrentCell(0, 1);
    }else if(this->currentMode == MainDialog::Video){
        this->ui->tableWidgetMode->setCurrentCell(0, 2);
    }else if(this->currentMode == MainDialog::Motion){
        this->ui->tableWidgetMode->setCurrentCell(1, 1);
    }else if(this->currentMode == MainDialog::AutoSnapping){
        this->ui->tableWidgetMode->setCurrentCell(1, 2);
    }
}
//================================================
void MainDialog::setCameraOnMode(){
    qDebug() << "void MainDialog::setCameraOnMode() called";
    bool camEnabled = this->enableCameraForOtherMode();
    if(camEnabled){
        this->ui->pushButtonRecord->setEnabled(false);
        this->ui->pushButtonRecord->setCheckable(false);
        this->ui->pushButtonShowDirectory->setEnabled(false);
        this->_setMode(MainDialog::CameraOn);
    }else{
        this->_setMode(MainDialog::CameraOff);
    }
    qDebug() << "void MainDialog::setCameraOnMode() end";
}
//================================================
bool MainDialog::enableCameraForOtherMode(){
    if(this->camera != NULL){
        this->camera->start();
        return true;
    }else{
        int nCamera = this->ui->comboBoxCamera->count();
        if(nCamera > 0){
            this->ui->comboBoxCamera->setCurrentIndex(1);
            return true;
        }else{
            QMessageBox::information(this, tr("No camera detected"), tr("You need to plug on at least one camera"));
            return false;
        }
    }
}
//================================================
void MainDialog::setCameraImageMode(){
    qDebug() << "void MainDialog::setCameraImageMode() called";
    bool camEnabled = this->enableCameraForOtherMode();
    if(camEnabled){
        this->_setMode(MainDialog::Image);
        this->camera->setCaptureMode(QCamera::CaptureStillImage);
        this->ui->pushButtonRecord->setEnabled(true);
        this->ui->pushButtonRecord->setCheckable(false);
        this->ui->pushButtonShowDirectory->setEnabled(true);
    }
    qDebug() << "void MainDialog::setCameraImageMode() end";
}
//================================================
void MainDialog::setCameraVideoMode(){
    qDebug() << "void MainDialog::setCameraVideoMode() called";
    bool camEnabled = this->enableCameraForOtherMode();
    if(camEnabled){
        this->_setMode(MainDialog::Video);
        this->camera->setCaptureMode(QCamera::CaptureVideo); //TODO try capture view finder pour les effets
        this->ui->pushButtonRecord->setEnabled(true);
        this->ui->pushButtonRecord->setCheckable(true);
        this->ui->pushButtonShowDirectory->setEnabled(true);
    }else{
        this->currentMode = MainDialog::CameraOff;
    }
    qDebug() << "void MainDialog::setCameraVideoMode() end";
}
//================================================
void MainDialog::setCameraAutoSnappingMode(){
    qDebug() << "void MainDialog::setCameraAutoSnappingMode() called";
    this->setCameraOffMode();
    this->setCameraOnMode();
    if(this->camera != NULL){
        this->camera->setCaptureMode(QCamera::CaptureStillImage);
        this->_setMode(MainDialog::AutoSnapping);
        this->ui->pushButtonRecord->setEnabled(true);
        this->ui->pushButtonRecord->setCheckable(true);
        this->ui->pushButtonShowDirectory->setEnabled(true);
    }
    qDebug() << "void MainDialog::setCameraAutoSnappingMode() end";
}
//================================================
void MainDialog::setCameraMotionMode(){
    qDebug() << "void MainDialog::setCameraMotionMode() called";
    this->setCameraOffMode();
    this->setCameraOnMode();
    if(this->camera != NULL){
        this->camera->setCaptureMode(QCamera::CaptureStillImage);
        this->_setMode(MainDialog::Motion);
        this->ui->pushButtonRecord->setEnabled(true);
        this->ui->pushButtonRecord->setCheckable(true);
        this->ui->pushButtonShowDirectory->setEnabled(true);
    }
    qDebug() << "void MainDialog::setCameraMotionMode() end";
}
//================================================
void MainDialog::showDirectory(){
    SettingsManagerSingleton *settingsManager
                    = SettingsManagerSingleton::getInstance();
    QString directoryString = "";
    if(this->currentMode == MainDialog::Image){
        directoryString = settingsManager->getImagesDirPath();
    }else if(this->currentMode == MainDialog::Video){
        directoryString = settingsManager->getVideosDirPath();
    }else if(this->currentMode == MainDialog::Motion){
        directoryString = settingsManager->getMotionDirPath();
    }else if(this->currentMode == MainDialog::AutoSnapping){
        directoryString = settingsManager->getAutoSnappingDirPath();
    }
    if(!directoryString.isEmpty()){
        QDir directory = directoryString;
        if(!directory.exists()){
            directory.mkpath(".");
        }
        QUrl url("file:///" + directory.path());
        QDesktopServices::openUrl(url);
    }
}
//================================================
void MainDialog::record(){
    qDebug() << "void MainDialog::record() called";
    if(this->currentMode == MainDialog::Image){
        this->recordImage();
    }else if(this->currentMode == MainDialog::Video){
        this->recordVideo();
    }else if(this->currentMode == MainDialog::Motion){
        this->recordMotion();
    }else if(this->currentMode == MainDialog::AutoSnapping){
        this->recordAutoSnapping();
    }
    qDebug() << "void MainDialog::record() end";
}
//================================================
//#include <QPrinter>
//#include <QPainter>
void MainDialog::recordImage(){
    qDebug() << "void MainDialog::recordImage() called";
    QDir imageDir = SettingsManagerSingleton::getInstance()
                    ->getImagesDirPath();
    if(!imageDir.exists()){
        imageDir.mkpath(".");
    }
    QDateTime dateTime = QDateTime::currentDateTime();
    QString dateTimeString = dateTime.toString();
    QString imageFileName = dateTimeString + ".jpg";
    imageFileName = imageFileName.replace(":", "-");
    QString imagePath =  imageDir.filePath(imageFileName);
    QCameraImageCapture imageCapture(this->camera.data());
    int ret = imageCapture.capture(imagePath);
    qDebug() << "ret: " << ret;
    //QPrinter printer;
    //QPainter p(&printer);
    //QPixmap pm = QPixmap::grabWindow(this->ui->mainCamViewWidget);
    //p.drawPixmap(0, 0, pm);
    //pm.save(imagePath);
    qDebug() << "void MainDialog::recordImage() end";
}
//================================================
void MainDialog::recordVideo(){
    bool recording = this->isRecording();
    if(recording){
        qDebug() << "this->recordVideoStart();";
        this->recordVideoStart();
    }else{
        this->recordVideoStop();
        qDebug() << "this->recordVideoStop();";
    }
}
//================================================
bool MainDialog::isRecording(){
    bool recording = this->ui->pushButtonRecord->isCheckable()
                         && this->ui->pushButtonRecord->isChecked();
    return recording;
}
//================================================
void MainDialog::recordVideoStart(){
    QSharedPointer<QMediaRecorder> localMediaRecorder(new QMediaRecorder(this->camera.data()));
    this->mediaRecorder = localMediaRecorder;
    /*
    QVideoEncoderSettings videoEncoderSettings;
    QAudioEncoderSettings audioEncoderSettings;
    videoEncoderSettings.setCodec("video/mpeg2");
    videoEncoderSettings.setResolution(640, 480);
    audioEncoderSettings.setCodec("audio/vorbis");
    //audioEncoderSettings.setQuality(QtMultimediaKit::HighQuality);
    this->mediaRecorder->setEncodingSettings(audioEncoderSettings, videoEncoderSettings);
    //*/

    QDateTime dateTime = QDateTime::currentDateTime();
    QString dateTimeString = dateTime.toString();
    dateTimeString = dateTimeString.replace(":", "-");
    QString videoFileName = dateTimeString + ".ogg";
    videoFileName = videoFileName.replace(" ", "_"); //TODO fixe that finding out why it doesn't work with file name with space
    QDir videoDir = SettingsManagerSingleton::getInstance()
                    ->getVideosDirPath();
    if(!videoDir.exists()){
        videoDir.mkpath(".");
    }
    QString videoPath =  videoDir.filePath(videoFileName);
    //videoPath = "D:\\code\\test.mpg";
    QUrl videoUrl(videoPath);

    qDebug() << "videoPath: " << videoPath;
    this->mediaRecorder->setOutputLocation(videoUrl);
    this->mediaRecorder->record();
    this->ui->pushButtonRecord->setText(STOP_RECORDING);
    qDebug() << "record started...";
}
//================================================
void MainDialog::recordVideoStop(){
    this->mediaRecorder->stop();
    this->ui->pushButtonRecord->setText(RECORD);
    qDebug() << "record done";
}
//================================================
void MainDialog::recordAutoSnapping(){
    qDebug() << "void MainDialog::recordAutoSnapping() called";
    bool recording = this->isRecording();
    bool emailSettingsFilled
                    = EmailManagerSingleton::getInstance()
                    ->isEmailSettingsFilled();
    SettingsManagerSingleton *settingsMananger
                    = SettingsManagerSingleton::getInstance();
    bool sendEmail = settingsMananger->getAutoSnappingSendEmail();
    if(recording){
        if(sendEmail && !emailSettingsFilled){
            this->ui->pushButtonRecord->setChecked(false);
            this->_enterEmailInformation();
        }else{
            this->timerAutoSnapping->stop();
            int timeIntervalInMs
                = settingsMananger->getAutoSnappingTimeIntervalInMs();
            qDebug() << "timeIntervalInMs: " << timeIntervalInMs;
            this->timerAutoSnapping->setInterval(timeIntervalInMs);
            this->timerAutoSnapping->start();
            qDebug() << "Timer started";
            this->ui->pushButtonRecord->setText(STOP_RECORDING);
        }
    }else{
        this->timerAutoSnapping->stop();
        qDebug() << "Timer stopped";
        this->ui->pushButtonRecord->setText(RECORD);
    }
    qDebug() << "void MainDialog::recordAutoSnapping() end";
}
//================================================
void MainDialog::_enterEmailInformation(){
    QMessageBox::warning(this,
             tr("Email information"),
             tr("You have to enter your email information."));
    this->ui->tabWidget->setCurrentIndex(2);
    this->ui->listWidget->setCurrentRow(3);
}
//================================================
void MainDialog::_recordAndSendImage(){
    qDebug() << "void MainDialog::_recordAndSendImage() called";
    QDir autoSnappingDir
                    = SettingsManagerSingleton::getInstance()
                    ->getAutoSnappingDirPath();
    if(!autoSnappingDir.exists()){
        autoSnappingDir.mkpath(".");
    }
    qDebug() << "autoSnappingDirPath:" << autoSnappingDir.currentPath();
    QDateTime dateTime = QDateTime::currentDateTime();
    QString dateTimeString = dateTime.toString();
    QString imageFileName = dateTimeString + ".jpg";
    imageFileName = imageFileName.replace(":", "-");
    QString imagePath =  autoSnappingDir.filePath(imageFileName);
    QCameraImageCapture imageCapture(this->camera.data());
    int ret = imageCapture.capture(imagePath);
    qDebug() << "Ret capture: " << ret;
    bool sendEmail = SettingsManagerSingleton::getInstance()
                    ->getAutoSnappingSendEmail();
    if(sendEmail){
        qDebug() << "Sending auto snapping email...";
        QString subject = tr("Auto Snapping ") + dateTimeString;
        QString content = tr("Auto Snapping done on the ")
                    + dateTimeString;
        EmailManagerSingleton::getInstance()
                    ->sendEmail(subject, content, imagePath);
    }
    qDebug() << "void MainDialog::_recordAndSendImage() end";
}
//================================================
void MainDialog::recordMotion(){
    bool recording = this->isRecording();
    if(recording){
        this->timerMotion->stop();
        int timeIntervalInMs
                    = SettingsManagerSingleton::getInstance()
                    ->getMotionTimeInterval();
        this->timerMotion->setInterval(timeIntervalInMs);
        this->timerMotion->start();
    }else{
        this->timerMotion->stop();
    }
}
//================================================
void MainDialog::_recordAndSendImageMotionEventually(){
    qDebug() << "void MainDialog::_recordAndSendImageMotionEventually() called";
    qDebug() << "void MainDialog::_recordAndSendImageMotionEventually() end";
}
//================================================
//================================================
void MainDialog::authenticationFailed(const QByteArray & msg){
   QString lastError = msg;
   QMessageBox::critical(this, tr("Authentication failed"), lastError + tr("\nImpossible d'envoyer l'email. Vérifier votre connexion internet et les informations entrées"));
}
//================================================
void MainDialog::connectionFailed(const QByteArray & msg){
   QString lastError = msg;
   QMessageBox::critical(this, tr("Connection failed"), lastError + tr("\nImpossible d'envoyer l'email. Vérifier votre connexion internet et les informations entrées"));
}
//================================================
void MainDialog::mailFailed(int mailID, int errorCode, const QByteArray & msg){
   QString lastError = msg;
   QMessageBox::critical(this, tr("Email failed"), lastError + tr("\nImpossible d'envoyer l'email. Vérifier votre connexion internet et les informations entrées"));
}
//================================================
// Settings tab
//================================================
void MainDialog::chooseImagesDirectory(){
    SettingsManagerSingleton *settingsManager
                    = SettingsManagerSingleton::getInstance();
    QString currentDir =
                    settingsManager->getImagesDirPath();
    QString dir = QFileDialog::getExistingDirectory(
                            this, CHOOSE_DIRECTORY,
                            currentDir,
                            QFileDialog::ShowDirsOnly
                            | QFileDialog::DontResolveSymlinks);
    if(!dir.isEmpty()){
        settingsManager->setImagesDirPath(dir);
    }
}
//================================================
void MainDialog::chooseVideosDirectory(){
    SettingsManagerSingleton *settingsManager
                    = SettingsManagerSingleton::getInstance();
    QString currentDir =
                    settingsManager->getVideosDirPath();
    QString dir = QFileDialog::getExistingDirectory(
                            this, CHOOSE_DIRECTORY,
                            currentDir,
                            QFileDialog::ShowDirsOnly
                            | QFileDialog::DontResolveSymlinks);
    if(!dir.isEmpty()){
        settingsManager->setVideosDirPath(dir);
    }
}
//================================================
void MainDialog::chooseAutoSnappingDirectory(){
    SettingsManagerSingleton *settingsManager
                    = SettingsManagerSingleton::getInstance();
    QString currentDir =
                    settingsManager->getAutoSnappingDirPath();
    QString dir = QFileDialog::getExistingDirectory(
                            this, CHOOSE_DIRECTORY,
                            currentDir,
                            QFileDialog::ShowDirsOnly
                            | QFileDialog::DontResolveSymlinks);
    if(!dir.isEmpty()){
        settingsManager->setAutoSnappingDirPath(dir);
    }
}
//================================================
void MainDialog::chooseMotionDirectory(){
    SettingsManagerSingleton *settingsManager
                    = SettingsManagerSingleton::getInstance();
    QString currentDir =
                    settingsManager->getMotionDirPath();
    QString dir = QFileDialog::getExistingDirectory(
                            this, CHOOSE_DIRECTORY,
                            currentDir,
                            QFileDialog::ShowDirsOnly
                            | QFileDialog::DontResolveSymlinks);
    if(!dir.isEmpty()){
        settingsManager->setMotionDirPath(dir);
    }
}
//================================================
void MainDialog::setImagesDirPath(QString imagesDirPath){
    QString currentText = this->ui->lineEditImagesDirectory->text();
    if(currentText != imagesDirPath){
        this->ui->lineEditImagesDirectory->setText(imagesDirPath);
    }
}
//================================================
void MainDialog::setVideosDirPath(QString videosDirPath){
    QString currentText = this->ui->lineEditVideosDirectory->text();
    if(currentText != videosDirPath){
        this->ui->lineEditVideosDirectory->setText(videosDirPath);
    }
}
//================================================
void MainDialog::setAutoSnappingDirPath(QString autoSnappingDirPath){
    QString currentText = this->ui->lineEditAutoSnappingDirectory->text();
    if(currentText != autoSnappingDirPath){
        this->ui->lineEditAutoSnappingDirectory->setText(autoSnappingDirPath);
    }
}
//================================================
void MainDialog::setMotionDirPath(QString motionDirPath){
    QString currentText = this->ui->lineEditMotioDirectory->text();
    if(currentText != motionDirPath){
        this->ui->lineEditMotioDirectory->setText(motionDirPath);
    }
}
//================================================
void MainDialog::setHidePasswordSender(bool hide){
    qDebug() << "void MainDialog::setHidePasswordSender(bool hide) begin";
    //bool currentCheck = this->ui->checkBoxHidePasswordSender->checkState();
    if(hide){
        this->ui->lineEditPasswordSender
                        ->setEchoMode(QLineEdit::Password);
    }else{
        this->ui->lineEditPasswordSender
                        ->setEchoMode(QLineEdit::Normal);
    }
    this->ui->checkBoxHidePasswordSender->setChecked(hide);
    qDebug() << "void MainDialog::setHidePasswordSender(bool hide) end";
}
//================================================
void MainDialog::setMotionSave(bool save){
    if(!save){
        this->ui->radioButtonMotionSaveImages->setChecked(false);
        this->ui->radioButtonMotionSaveVideos->setChecked(false);
    }
    SettingsManagerSingleton *settingsManager
                    = SettingsManagerSingleton::getInstance();
    settingsManager->setMotionSave(save);
}
//================================================
